package com.company.project.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.project.common.job.CorporOV;
import com.company.project.common.job.OvsAndMiddlenum;
import com.company.project.common.redismq.ZSetVer;
import com.company.project.common.utils.Func;
import com.company.project.common.utils.StringUtil;
import com.company.project.entity.*;
import com.company.project.mapper.*;
import com.company.project.service.TCallbakTaskArcService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("tCallbakTaskArcService")
public class TCallbakTaskArcServiceImpl extends ServiceImpl<TCallbakTaskMapper, TCallbakTaskEntity> implements TCallbakTaskArcService {

    @Autowired
    public TSeatsMapper tSeatsMapper;
    @Autowired
    public TXiaohaoMapper xiaohaoMapper;
    @Resource
    public TCallbakTaskMapper tCallbakTaskMapper;
    @Resource
    private SysUserMapper sysUserMapper;

    @Autowired
    private TCallbakMapper callbakMapper;
    @Autowired
    private TCallbakLogMapper callbakLogMapper;
    @Autowired
    private TThjlmxMapper thjlmxMapper;
    @Autowired
    public TThrbMapper thrbMapper;
    @Autowired
    private THwtjMapper hwtjMapper;

    @Autowired
    private TMiddlenumMapper tMiddlenumMapper;
    @Autowired
    private TXiaohaoMapper tXiaohaoMapper;
    @Autowired
    private TWhbcsMapper tWhbcsMapper;
    @Autowired
    public TBacklistMapper backlistMapper;

    @Autowired
    private ZSetVer zSetVer;
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public Map<String, Object> notifyurl1(CallbackEntityVo1 vo) {
        Map<String, Object> map = new HashMap<>();
        try {
//            log.info("Callbak回调参数: " + vo.toString());
            Date date = new Date();
            TCallbakLogEntity tCallbakLog = new TCallbakLogEntity();
            tCallbakLog.setBindId(vo.getSessionId());//绑定 ID
            tCallbakLog.setZjh(vo.getBindNbr());//中间号
            tCallbakLog.setZjhm(vo.getCallerNbr());//主叫号码
            tCallbakLog.setBjhm(vo.getCalleeNbr());//被叫号码
            tCallbakLog.setStartTime(vo.getStartTime());
            tCallbakLog.setEndTime(vo.getEndTime());
            tCallbakLog.setCallOutStartTime(vo.getCallOutStartTime());
            tCallbakLog.setDuration(vo.getDuration());
            tCallbakLog.setRecordUrl(vo.getRecordUrl());//录音地址
            tCallbakLog.setStatus(vo.getStatus());
            tCallbakLog.setUlFailReason(vo.getUlFailReason());
            tCallbakLog.setAddtime(date);

            String cUserId = "";
            //2次 回调不记录
            TCallbakEntity callbakUser = callbakMapper.selectOneBySessionId(vo.getSessionId());
            if (callbakUser == null) {
                log.info("notifyurl1--task: {}", tCallbakLog.toString());
                return null;
            } else {
                cUserId = callbakUser.getUserid();
            }

            if (callbakUser == null) {
                TThjlmxEntity tThjlmx = thjlmxMapper.selectOneBySessionId(vo.getSessionId());
                SysUser sysUserOne = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, tThjlmx.getYgxm())
                        .eq(SysUser::getDeptId,tThjlmx.getOrg()));
                if (sysUserOne != null) {
                    cUserId = sysUserOne.getId();
                }else {
                    log.info("notifyurl1--task: {}", tCallbakLog.toString());
                    return null;
                }
            } else {
                cUserId = callbakUser.getUserid();
            }
            //通话人
            TSeatsEntity tSeatsEntity = tSeatsMapper.selectById(cUserId);
            SysUser sysUser = sysUserMapper.selectById(tSeatsEntity.getAccountid());
            if (sysUser == null) {
                sysUser = new SysUser();
                sysUser.setUsername("admin");
            }
            String line = tSeatsEntity.getLine();
            String ulFailReason = vo.getUlFailReason();
            if (Func.isEmpty(ulFailReason)) {
                if (Func.equals("有销移动", line)) {
                    ulFailReason = "yx未知";
                }
            }
//            List<TCallbakLogEntity> tCallbakLogList = callbakLogMapper.selectList(Wrappers.<TCallbakLogEntity>lambdaQuery()
//                    .eq(TCallbakLogEntity::getBindId, vo.getSessionId()));

            List<TThjlmxEntity> ttList = thjlmxMapper.selectList(Wrappers.<TThjlmxEntity>lambdaQuery()
                    .eq(TThjlmxEntity::getBindId, vo.getSessionId()));

            List<TThrbEntity> tThrbEntities = thrbMapper.selectList(Wrappers.<TThrbEntity>lambdaQuery()
                    .eq(TThrbEntity::getBindId, vo.getSessionId()));

            List<THwtjEntity> tHwtjEntities = hwtjMapper.selectList(Wrappers.<THwtjEntity>lambdaQuery()
                    .eq(THwtjEntity::getBindId, vo.getSessionId()));

            TThjlmxEntity tt = new TThjlmxEntity();
            if (ttList.size() > 0) {
                tt = ttList.get(0);
            }

            if (tThrbEntities.size() > 0|| tHwtjEntities.size()>0) {
                log.info("通话日报已存在:{}", vo.getSessionId());
                log.info("话务统计已存在:{}", vo.getSessionId());
                //记录通话明细
                if (Func.isNotEmpty(vo.getRecordUrl()) && tt.getId() != null) {
                    tt.setLy(vo.getRecordUrl());//录音
                    tt.setHdstart("4"); //回调状态
                    // thjlmxMapper.updateById(tt);
                    map.put("thjlmx", tt);
                    log.info("2次回调 thjlmx不为空: " + tCallbakLog.toString());
                    return map;
                }
                return map;
            }

            if (tCallbakLog.getBjhm() == null || Func.isEmpty(tCallbakLog.getStatus())) {
                //记录通话明细
                if (Func.isNotEmpty(vo.getRecordUrl())) {
                    tt.setLy(vo.getRecordUrl());//录音
                    tt.setHdstart("4"); //回调状态
                    map.put("thjlmx", tt);
                }
                log.info("2次回调 tCallbakLog不为空: " + tCallbakLog.toString());
                return map;
            }
            if (Func.equals("", tCallbakLog.getStatus())) {
                //记录通话明细
                if (Func.isNotEmpty(vo.getRecordUrl())) {
                    tt.setLy(vo.getRecordUrl());//录音
                    tt.setHdstart("4"); //回调状态
                    map.put("thjlmx", tt);
                }
                log.info("2次回调 tCallbakLog不为空: " + tCallbakLog.toString());
                return map;
            }

            String thsc = "0";
            long seconds = 0;
            long minutes = 0;
            String jts = "0";//接通数
            if (Func.equals("1", vo.getStatus())) {
                //通话时长  seconds 不足一分钟按一分钟计算
                thsc = String.valueOf(DateUtil.between(vo.getStartTime(), vo.getEndTime(), DateUnit.SECOND));
                seconds = DateUtil.between(vo.getStartTime(), vo.getEndTime(), DateUnit.SECOND);
                minutes = seconds / 60;
                seconds -= minutes * 60;
                //计费分钟数 minutes
                if (seconds > 0) {
                    minutes++;
                }
                jts = "1";
            }

            if (tt != null) {
                //记录通话明细
                if (Func.isNotEmpty(vo.getRecordUrl())) tt.setLy(vo.getRecordUrl());//录音
                if (sysUser != null && Func.isNotEmpty(sysUser.getUsername())) tt.setYgxm(sysUser.getUsername());//员工姓名
                if (Func.isNotEmpty(vo.getCallerNbr())) tt.setZjhm(vo.getCallerNbr());
                if (Func.isNotEmpty(vo.getBindNbr())) tt.setXh(vo.getBindNbr());//小号
                if (Func.isNotEmpty(vo.getCalleeNbr())) tt.setBjhm(vo.getCalleeNbr());//被叫号码
                if (StringUtil.isNotBlank(vo.getRecordUrl())&& vo.getRecordUrl() != null && vo.getRecordUrl().length() > 0) {
                    tt.setStart("1");//状态
                } else {
                    if (Func.isNotEmpty(vo.getStatus())) tt.setStart(vo.getStatus());//状态
                }
                if (Func.isNotEmpty(ulFailReason)) tt.setStartinfo(ulFailReason);//状态明细
                if (Func.isNotEmpty(vo.getCallOutStartTime())) tt.setZjjttime(vo.getCallOutStartTime());//主叫接通时间
                if (Func.isNotEmpty(vo.getStartTime())) tt.setBjjttime(vo.getStartTime());//被叫接通时间
                if (Func.isNotEmpty(vo.getEndTime())) tt.setEndtime(vo.getEndTime());//结束时间
                if (Func.isNotEmpty(thsc) && Func.isNotEmpty(vo.getEndTime())) tt.setThsc(thsc);//通话时长
                if (Func.isNotEmpty(tSeatsEntity.getDept())) tt.setOrg(tSeatsEntity.getDept());//所属部门
                if (Func.isEmpty(tt.getCtime())) tt.setCtime(new Date());
                tt.setHdstart("4"); //回调状态
                tt.setBindId(vo.getSessionId());//外呼回调唯一ID
//            thjlmxMapper.updateById(tt);
                map.put("thjlmx", tt);
                log.info("记录通话明细:{}", tt.toString());
            }

            //公司主坐席
            TSeatsEntity gsgl = tSeatsMapper.selectOne(Wrappers.<TSeatsEntity>lambdaQuery()
                    .eq(TSeatsEntity::getCorporatename, tSeatsEntity.getCorporatename()
                    ).eq(TSeatsEntity::getGsgl, "1"));
            Integer xhfzs = Integer.valueOf(gsgl.getResidue()) - (int) minutes;
            log.info("{}扣除分钟数为:{}", tSeatsEntity.getCorporatename(), minutes);
            map.put("corporatename", tSeatsEntity.getCorporatename());
            map.put("minutes", minutes);

            //通话日报 t_thrb
            TThrbEntity thrb = new TThrbEntity();
            thrb.setUsername(sysUser.getUsername());
            thrb.setOrg(tSeatsEntity.getDept());
            thrb.setCompany(tSeatsEntity.getCorporatename());
            thrb.setJts(jts);
            String bdcs = "1";//拨打次数
            thrb.setBdcs(bdcs);
            thrb.setThsc(thsc);//通话时长
            thrb.setJfsc(String.valueOf(minutes));//计费时长
            thrb.setThtime(date);//通话时间
            thrb.setXs(tSeatsEntity.getSalesname());//销售
            thrb.setBindId(vo.getSessionId());//回调唯一id
            map.put("thrb", thrb);
//        thrbMapper.insert(thrb);
            log.info("通话日报:{}", thrb.toString());

            //话务统计 t_hwtj
            THwtjEntity hwtj = hwtjMapper.selectOneByCorporatename(tSeatsEntity.getCorporatename());
            Date nowData = date;
            if (nowData.equals(hwtj.getDate())) {
                long timeInMillis = nowData.getTime(); // 转换为毫秒数
                timeInMillis += 1000; // 加1秒（1000毫秒）
                nowData.setTime(timeInMillis); // 更新时间
            }
            double random = Math.random() * 100;
            String sessionId = vo.getSessionId();
            hwtj.setId(sessionId);
            hwtj.setCompany(tSeatsEntity.getCorporatename());//公司名称
            hwtj.setSyfzs(gsgl.getResidue());
            hwtj.setBscs(bdcs);
            hwtj.setJts(jts);
            hwtj.setJfsc(String.valueOf(minutes));//计费时长
            hwtj.setThsc(thsc);//通话时长
            hwtj.setXs(tSeatsEntity.getSalesname());//销售
            hwtj.setOrgname(tSeatsEntity.getDept());//所属部门
            hwtj.setLine(tSeatsEntity.getLine());//线路
            hwtj.setDate(nowData);
            hwtj.setBindId(vo.getSessionId());//回调唯一id
            String createuser = gsgl.getCreateuser();
            if (!Func.equals("guest", createuser)) {//非管理员创建 就是代理商
                hwtj.setDl(createuser);//代理商
            }
            map.put("hwtj", hwtj);
//        hwtjMapper.insert(hwtj);
            log.info("话务统计:{}", hwtj.toString());

            if (!Func.equals(vo.getBindNbr(), vo.getCallerNbr())) {
                log.info("中间号:{}", vo.getBindNbr());
                log.info("主叫号码:{}", vo.getCallerNbr());
                //中间号  减去剩余分钟数
                TMiddlenumEntity tMiddlenumEntity = tMiddlenumMapper.selectOne(Wrappers.<TMiddlenumEntity>lambdaQuery()
                        .eq(TMiddlenumEntity::getMiddlenum, vo.getBindNbr()));
                if (tMiddlenumEntity != null) {
                    map.put("tMiddlenumEntity", tMiddlenumEntity);
                }
            }
            //记录未接通数据
            if (Func.equals("2", vo.getStatus())) {
                TWhbcsEntity tWhbcs = new TWhbcsEntity();
                tWhbcs.setXh(vo.getBindNbr());
                tWhbcs.setDate(date);
                tWhbcs.setWhbcs(1);
                map.put("tWhbcs", tWhbcs);
//                tWhbcsMapper.insert(tWhbcs);
            }
            log.info("记录结束");
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }


    @Override
    public String runCallBack(List<TCallbakTaskEntity> tCallbakTaskEntities) {
        List<String> sessionIds = new ArrayList<>();
        List<String> bakIds = new ArrayList<>();
        List<String> corporatenames = new ArrayList<>();
        List<CorporOV> ovs = new ArrayList<>();
        List<TCallbakLogEntity> callLogList = new ArrayList<>();
        List<TThrbEntity> thrbList = new ArrayList<>();
        List<THwtjEntity> hwtjList = new ArrayList<>();
        List<TWhbcsEntity> whbcsList = new ArrayList<>();
        List<TThjlmxEntity> thjlmxList = new ArrayList<>();
        List<TMiddlenumEntity> middlenumEntityList = new ArrayList<>();
        List<String> middlenums = new ArrayList<>();
        //记入日志
        callbakLogMapper.insertByCallList(tCallbakTaskEntities);
//        //删除需要计算的数据

        for (TCallbakTaskEntity task : tCallbakTaskEntities) {
            CallbackEntityVo1 vo = new CallbackEntityVo1();
            vo.setSessionId(task.getBindId());//绑定 ID
            vo.setBindNbr(task.getZjh());//中间号
            vo.setCallerNbr(task.getZjhm());//主叫号码
            vo.setCalleeNbr(task.getBjhm());//被叫号码
            vo.setStartTime(task.getStartTime());
            vo.setEndTime(task.getEndTime());
            vo.setCallOutStartTime(task.getCallOutStartTime());
            vo.setDuration(task.getDuration());
            vo.setRecordUrl(task.getRecordUrl());//录音地址
            vo.setStatus(task.getStatus());
            vo.setUlFailReason(task.getUlFailReason());

            try {
                long start = System.currentTimeMillis();
                //开始计算
                Map<String, Object> map = notifyurl1(vo);

                long end = System.currentTimeMillis();
                log.info("notifyurl1总耗时：{} ms", end - start);
                if (map == null) {
//                    String jsonString = JSON.toJSONString(task);
//                    zSetVer.producer("callBackYXTask",jsonString);

                    log.info("没有从Redis中获取到notifyurl1--task: {}", task.toString());
                    continue;
                }
                log.info("notifyurl1--map: {}", map.toString());

                TCallbakLogEntity tCallbakLog = (TCallbakLogEntity) map.get("tCallbakLog");
                if (tCallbakLog != null) callLogList.add((TCallbakLogEntity) map.get("tCallbakLog"));
                TThrbEntity tThrb = (TThrbEntity) map.get("thrb");
                if (tThrb != null) thrbList.add((TThrbEntity) map.get("thrb"));
                THwtjEntity hwtj = (THwtjEntity) map.get("hwtj");
                if (hwtj != null) {
                    THwtjEntity hwtjNew = new THwtjEntity();
                    hwtjNew.setId(task.getBindId());
                    hwtjNew.setCompany(hwtj.getCompany());//公司名称
                    hwtjNew.setSyfzs(hwtj.getSyfzs());
                    hwtjNew.setFzsze(hwtj.getFzsze());
                    hwtjNew.setBscs(hwtj.getBscs());
                    hwtjNew.setJts(hwtj.getJts());
                    hwtjNew.setJfsc(hwtj.getJfsc());//计费时长
                    hwtjNew.setThsc(hwtj.getThsc());//通话时长
                    hwtjNew.setXs(hwtj.getXs());//销售
                    hwtjNew.setOrgname(hwtj.getOrgname());//所属部门
                    hwtjNew.setLine(hwtj.getLine());//线路
                    hwtjNew.setDate(hwtj.getDate());
                    hwtjNew.setBindId(task.getBindId());//回调唯一id
                    hwtjNew.setDl(hwtj.getDl());//代理商
                    hwtjList.add(hwtjNew);
                }

                start = System.currentTimeMillis();

                TWhbcsEntity tWhbcs = (TWhbcsEntity) map.get("tWhbcs");
                if (tWhbcs != null) whbcsList.add((TWhbcsEntity) map.get("tWhbcs"));
                TThjlmxEntity tThjlmx = (TThjlmxEntity) map.get("thjlmx");
                if (tThjlmx != null) thjlmxList.add((TThjlmxEntity) map.get("thjlmx"));

                sessionIds.add(vo.getSessionId());
                bakIds.add(task.getId());
                if (map.get("minutes") != null) {
                    String s = String.valueOf(map.get("corporatename"));
                    //是否已存在这个公司数据
                    boolean contains = corporatenames.contains(s);
                    int integer = Integer.valueOf(String.valueOf(map.get("minutes")));
                    logger.info("{}扣除分钟数为:{}", s, integer);
                    if (contains) {
                        for (CorporOV ov : ovs) {
                            //有相同的公司统计分钟数
                            if (StringUtil.equals(ov.getCorporatename(), s)) {
                                int minutes = ov.getMinutes();
                                ov.setMinutes(minutes + integer);
                            }
                        }
                    } else {
                        CorporOV corporOV = new CorporOV();
                        corporOV.setCorporatename(s);
                        corporOV.setMinutes(integer);

                        ovs.add(corporOV);
                        corporatenames.add(s);
                    }
                }
                //中间号处理
                if (map.get("tMiddlenumEntity") != null) {
                    TMiddlenumEntity tMiddlenumEntity = (TMiddlenumEntity) map.get("tMiddlenumEntity");
                    //是否已存在这个公司数据
                    boolean contains = middlenums.contains(tMiddlenumEntity.getMiddlenum());
                    if (contains) {
                        for (TMiddlenumEntity ov : middlenumEntityList) {
                            //有相同的公司统计分钟数
                            if (StringUtil.equals(ov.getMiddlenum(), tMiddlenumEntity.getMiddlenum())) {
                                int minutes = ov.getSycs();
                                ov.setSycs(minutes + 1);
                            }
                        }

                    } else {
                        TMiddlenumEntity o = new TMiddlenumEntity();
                        o.setMiddlenum(tMiddlenumEntity.getMiddlenum());
                        o.setSycs(1);
                        middlenums.add(tMiddlenumEntity.getMiddlenum());
                        middlenumEntityList.add(o);
                    }
                }
                end = System.currentTimeMillis();
                log.info("中间号处理 总耗时：{} ms", end - start);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            long start = System.currentTimeMillis();
            if (callLogList.size() > 0) {
                ArrayList<TCallbakLogEntity> collect = callLogList.stream()
                        .collect(Collectors.collectingAndThen(Collectors
                                .toCollection(() -> new TreeSet<>(Comparator
                                        .comparing(s -> s.getBindId()))), ArrayList::new));
//                collect.forEach(System.out::println);
                callbakLogMapper.insertList(collect);
            }
            long end = System.currentTimeMillis();
            log.info("callLogList 总耗时：{} ms", end - start);

            start = System.currentTimeMillis();
            if (thrbList.size() > 0) {
                ArrayList<TThrbEntity> collect = thrbList.stream()
                        .collect(Collectors.collectingAndThen(Collectors
                                .toCollection(() -> new TreeSet<>(Comparator
                                        .comparing(s -> s.getBindId()))), ArrayList::new));
//                collect.forEach(System.out::println);
                thrbMapper.insertList(collect);
            }
            end = System.currentTimeMillis();
            log.info("thrbList 总耗时：{} ms", end - start);


            start = System.currentTimeMillis();
            if (hwtjList.size() > 0) {
                ArrayList<THwtjEntity> collect = hwtjList.stream()
                        .collect(Collectors.collectingAndThen(Collectors
                                .toCollection(() -> new TreeSet<>(Comparator
                                        .comparing(s -> s.getBindId()))), ArrayList::new));
//                collect.forEach(System.out::println);
                hwtjMapper.insertList(collect);
            }
            end = System.currentTimeMillis();
            log.info("hwtjList 总耗时：{} ms", end - start);

            if (whbcsList.size() > 0) tWhbcsMapper.insertList(whbcsList);

            start = System.currentTimeMillis();


            OvsAndMiddlenum ovsAndMiddlenum = new OvsAndMiddlenum();
            ovsAndMiddlenum.setCov(ovs);
            ovsAndMiddlenum.setMiddlenum(middlenumEntityList);

            if(ovs.size() > 0)
            tWhbcsMapper.insetCorpor(ovs);
            if(middlenumEntityList.size() > 0)
            tWhbcsMapper.insetMiddlenum(middlenumEntityList);

            long start3 = System.currentTimeMillis();
            logger.info("CallBackTask定时任务  thjlmxList.size() :" + thjlmxList.size());
            if (thjlmxList.size() > 0) {
                thjlmxMapper.deleteListById(thjlmxList);
                thjlmxMapper.insertList(thjlmxList);
            }
            long end3 = System.currentTimeMillis();
            log.info("thjlmxList 总耗时：{} ms", end3 - start3);

            start3 = System.currentTimeMillis();
            if (sessionIds.size() > 0) {
                Date calltime = tCallbakTaskEntities.get(0).getAddtime();//呼叫时间
                tCallbakTaskMapper.deleteHJ(calltime);
                tCallbakTaskMapper.insertHJ(calltime);

//                tCallbakTaskMapper.updateFlag(tCallbakTaskEntities);
//                tCallbakTaskMapper.deleteByFlag(bakIds);
            }
            end3 = System.currentTimeMillis();
            log.info("tCallbakTaskMapper.deleteByFlag总耗时：{} ms", end3 - start3);
            return "jsonString";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public Map<String, Object> notifyurl1Test(CallbackEntityVo1 vo) {
        return null;
    }

    @Override
    public String runCallBackTest(List<TCallbakTaskEntity> tCallbakTaskEntities) {
        return null;
    }
}
